package pokerserver.core;

import java.util.Arrays;

import common.Card;

/**
 * A class representing a hand. A hand is the total amount of cards, including
 * those the player have control of, as well as the public cards on the table.
 * (a total of 7, but only 5 of them count when comparing the hands)
 * 
 * @author Marcus Harryson, Aron Manucheri
 * 
 */
public class Hand {

	/** Class variables */
	private Card[] hand = new Card[7];
	private HandCategory category; // what kind of hand is this (flush, pair,
									// etc.)

	/**
	 * A simple constructor to create and set the two cards in the hand
	 * (simulating the cards a player have when no cards are on the table).
	 * 
	 * This is mostly used for testing purposes, or some rare occation where
	 * it's needed. In the game environment the other contructor, which takes in
	 * a deck as a parameter, should be called instead.
	 */
	public Hand(Card card1, Card card2) {
		this.hand[0] = card1;
		this.hand[1] = card2;
	}

	/**
	 * Constructor. Creates a new hand with two starting cards, drawing the
	 * cards from a deck.
	 * 
	 * @param deck
	 *            the deck of the game.
	 */
	public Hand(Deck deck) {
		for (int i = 0; i < 2; i++) {
			if (deck != null) {
				hand[i] = deck.drawCard();
			} else {
				hand[i] = null;
			}
		}
	}

	/**
	 * Because of the only cards differing between players, it is needed to get
	 * these two cards.
	 * 
	 * @return the two cards the player has control over (not the public cards)
	 */
	public Card[] getPlayerCards() {
		Card[] privateHand = new Card[2];
		privateHand[0] = this.hand[0];
		privateHand[1] = this.hand[1];
		return privateHand;
	}

	/**
	 * 
	 * @return all cards in this hand (including those on the table)
	 */
	public Card[] getAllCards() {
		return this.hand;
	}

	@Override
	public String toString() {
		return Arrays.toString(hand);
	}

	/**
	 * Takes in the community cards and adds them at the end of this hand.
	 * 
	 * @param communityCards
	 *            The cards on the table.
	 */
	public void setCommunityCards(Card[] communityCards) {
		for (int i = 2; i < 7; i++) {
			this.hand[i] = communityCards[i - 2];
		}
	}

	/**
	 * Set what kind of hand this is (done when evaulating cards)
	 * 
	 * @param category
	 *            the category of this hand
	 */
	public void setCategory(HandCategory category) {
		this.category = category;
	}

	/**
	 * Return the category
	 * 
	 * @return the category of the hand
	 */
	public HandCategory getCategory() {
		return this.category;
	}

	/**
	 * All kind of types/categories of hands (enumeration values)
	 */
	public enum HandCategory {
		HIGH_CARD, ONE_PAIR, TWO_PAIR, THREE_OF_A_KIND, STRAIGHT, FLUSH, FULL_HOUSE, FOUR_OF_A_KIND, STRAIGHT_FLUSH
	}
}
